package com.google.gwt.sample.dynatablerf.client.presenters;

import java.util.HashMap;
import java.util.Map;

import com.google.gwt.event.logical.shared.HasSelectionHandlers;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.sample.dynatablerf.client.events.GrifoSuggestEvent;
import com.google.gwt.sample.dynatablerf.client.events.GrifoSuggestEventHandler;
import com.google.gwt.sample.dynatablerf.client.util.GrifoConstants;
import com.google.gwt.sample.dynatablerf.client.widgets.HasGrifoSuggestHandler;
import com.google.gwt.sample.dynatablerf.client.widgets.HasMenuItens;
import com.google.gwt.sample.dynatablerf.shared.GrifoRequestFactory;
import com.google.gwt.sample.dynatablerf.shared.GrifoSharedConstants;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.SuggestOracle;
import com.google.gwt.user.client.ui.SuggestOracle.Callback;
import com.google.gwt.user.client.ui.SuggestOracle.Request;
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
import com.google.gwt.view.client.SelectionChangeEvent.HasSelectionChangedHandlers;
import com.google.web.bindery.requestfactory.shared.EntityProxy;
import com.google.web.bindery.requestfactory.shared.RequestContext;

public abstract class AbstractSearchDataPresenter<E extends EntityProxy, T extends RequestContext>
		extends AbstractHasDataTabPresenter<E, T> {

	public interface SearchDataDisplay<E extends EntityProxy> extends
			HasDataDiplay<E> {
		HasSelectionHandlers<Suggestion> getHasSuggestionSelectionHandlers();

		HasGrifoSuggestHandler getGrifoSuggestHandler();

		HasSelectionChangedHandlers getSelectionChangedHandlers();

		void populateSearchMenuOptions(Map<String, Command> menuItens);

		HasMenuItens getHasMenuItens();
	}

	public AbstractSearchDataPresenter(EventBus eventBus,
			GrifoRequestFactory requestFactory) {
		super(eventBus, requestFactory);
	}

	@Override
	protected void bind() {
		super.bind();

		getSearchDataDisplay()
				.getGrifoSuggestHandler()
				.getEventBus()
				.addHandler(GrifoSuggestEvent.TYPE,
						new GrifoSuggestEventHandler() {

							@Override
							public void onGrifoSuggest(GrifoSuggestEvent event) {
								fetchSuggestions(event.getRequest(),
										event.getCallback());

							}
						});

		getSearchDataDisplay().getHasSuggestionSelectionHandlers()
				.addSelectionHandler(
						new SelectionHandler<SuggestOracle.Suggestion>() {

							@Override
							public void onSelection(
									SelectionEvent<Suggestion> event) {
								onFetchSelection(event);
							}
						});

		getSearchDataDisplay().populateSearchMenuOptions(getMenuSearchItens());
	}

	protected abstract SearchDataDisplay<E> getSearchDataDisplay();

	protected abstract void fetchSuggestions(final Request request,
			final Callback callback);

	protected abstract void onFetchSelection(SelectionEvent<Suggestion> event);

	protected Map<String, Command> getMenuSearchItens() {
		Map<String, Command> map = new HashMap<String, Command>();

		Command command = new Command() {

			@Override
			public void execute() {
				getHasDataDisplay().getData().setVisibleRange(0,
						GrifoSharedConstants.GRID_NUM_ROWS);
			}
		};

		map.put(GrifoConstants.INSTANCE.procurarTodos(), command);

		Command command2 = new Command() {

			@Override
			public void execute() {
				//goToPesquisaAvancada();

			}
		};

		map.put(GrifoConstants.INSTANCE.pesquisaAvancada(), command2);
		return map;

	}

	@Override
	protected HasDataDiplay<E> getHasDataDisplay() {
		return getSearchDataDisplay();
	}

}
